/* 二分图
* 1.二分图、不存在奇数环、染色法不存在矛盾
* 2.匈牙利算法，匹配、最大匹配、匹配点、增广路径
* 3.最小点覆盖、最大独立集、最小路径点覆盖(最小路径重复点覆盖)
    最大匹配数 = 最小点覆盖 = 总点数-最大独立集 = 总点数-最小路径覆盖
*/

#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
// #define ONLINE_GUDGE
using namespace std;
using LL = unsigned long long;
const int N = 200010, M = 200010, INF = 0x3f3f3f3f;

int n, m;
int h[N], e[M], ne[M], w[N], idx;
int color[N]; // 0未染色 1白色 2黑色

void AddEdge(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a],  w[idx] = c, h[a] = idx ++; // 
}

bool dfs(int u, int c, int limit)
{
    color[u] = c;
    for(int i = h[u]; ~i; i = ne[i])
    {
        int v = e[i];
        if(w[i] <= limit) continue; // 比当前影响力小的都不考虑
        if(color[v]){
            if(color[v] == c) return false;
        }
        else if(!dfs(v, 3-c, limit)) return false;    
    }
    return true;
}

bool check(int limit)
{
    memset(color, 0, sizeof color);

    for(int i = 1; i <= n; i++)
        if(color[i] == 0)
            if(!dfs(i, 1, limit)) return false;
    return true;
}

int main()
{

    #ifdef ONLINE_JUDGE

    #else
    freopen("./in.txt","r",stdin);
    #endif
    ios::sync_with_stdio(false);   
	cin.tie(0);
    
    cin >> n >> m;

    memset(h, -1, sizeof h);

    while(m--)
    {
        int a, b, c; cin >> a >> b >> c;
        AddEdge(a, b, c); AddEdge(b, a, c);
    }

    int l =0, r = 1e9;
    while(l < r)
    {
        int limit = (l + r) >> 1; // 即当前可以接受的最大影响力
        if(check(limit)) r = limit;
        else l = limit + 1; // 当前有解，考虑更大值
    }

    cout << r << endl;
    return 0;
}